#ifndef __BTL_PROTOCOL_PACKAGE_H__
#define __BTL_PROTOCOL_PACKAGE_H__
#include <stdint.h>

#define FP_MOH 0x00
#define FP_MOC 0x10

#define FP_RUNNING_ON_BOOT 0x00
#define FP_RUNNING_ON_APP  0x01

#define PROTOCOL_MAX_PAYLOAD_SIZE (4 * 1024)

#define PROTOCOL_SYNC  0xAA
#define PROTOCOL_MAGIC 0x4C

#define PROTOCOL_RANDOM_SIZE 16

#define __BTL_PROTOCOL_CHECKSUM__
/* unsupported unknown-size array */
#define __UNSUPPORTED_UNKNOWN_SIZE_ARRAY__

struct package_header {
    uint8_t sync;
    uint32_t total_length;
} __attribute__((packed));

struct package_random {
    union {
        uint8_t data[PROTOCOL_RANDOM_SIZE];
        uint32_t p[4];
    } __attribute__((packed)) r;
} __attribute__((packed));

struct encrypt_header {
    uint8_t magic;
    uint8_t command0;
    uint8_t command1;
    uint8_t reserve;
    uint16_t index; /* index of frame */
    uint32_t payload_size;
} __attribute__((packed));

struct encrypt_data {
    struct encrypt_header header;
#ifdef __UNSUPPORTED_UNKNOWN_SIZE_ARRAY__
    uint8_t payload[1];
#else
    uint8_t payload[];
#endif /* __UNSUPPORTED_UNKNOWN_SIZE_ARRAY__ */
    // uint8_t paddding[];
} __attribute__((packed));

struct btl_protocol_package {
    struct package_header header;
    struct package_random random;
    struct encrypt_data crypt; /* 16-byte alignment */
#ifdef __BTL_PROTOCOL_CHECKSUM__
    uint32_t crc32;
#endif
} __attribute__((packed));

typedef struct package_header package_header_t;
typedef struct btl_protocol_package package_t;
typedef struct encrypt_data encrypt_data_t;
typedef struct encrypt_header encrypt_header_t;
typedef struct package_random package_random_t;

/* Enroll CMD1 */
#define FP_CMD1_ENROLL_START  0x00
#define FP_CMD1_ENROLL        0x01
#define FP_CMD1_ENROLL_END    0x02
#define FP_CMD1_ENROLL_CANCLE 0x03

/* Verify CMD1 */
#define FP_CMD1_VERIFY        0x00
#define FP_CMD1_VERIFY_CANCLE 0x01
#define FP_CMD1_VERIFY_GID    0x03 /* gid[32] */

/* Remove CMD1 */
#define FP_CMD1_REMOVE     0x00
#define FP_CMD1_REMOVE_ALL 0x01

/* Capture CMD1*/
#define FP_CMD1_CAPTURE_START  0x00
#define FP_CMD1_CAPTURE        0x01
#define FP_CMD1_CAPTURE_CANCLE 0x02

/* BOOT IAP CMD1 */
#define FP_CMD1_IAP_UPDATE_START 0x00
#define FP_CMD1_IAP_UPDATE       0x01
#define FP_CMD1_IAP_UPDATE_END   0x02

typedef enum FINGERPRINT_COMMAND0 {
    /* 4.1 查询固件版本 - 0xA0 */
    FP_CMD0_VERSION = 0xA0,
    /* 4.2 获取模组方案信息 - 0xA1 */
    FP_CMD0_SOLUTION = 0xA1,
    /* 4.3 获取根密钥 - 0xA2 */
    FP_CMD0_EXCHANGE_KEY = 0xA2,
    /* 4.4 注册指纹 - 0xB0 */
    FP_CMD0_DO_ENROLL = 0xB0,
    /* 4.5 比对指纹 - 0xB1 */
    FP_CMD0_DO_VERIFY = 0xB1,
    /* 4.6 删除指纹 - 0xB2 */
    FP_CMD0_DO_REMOVE = 0xB2,
    /* 4.7 查询指纹数量 - 0xB3 */
    FP_CMD0_DO_ENUMERATE = 0xB3,
    /* 4.8 获取指纹数据 - 0xB4 */
    FP_CMD0_DO_CAPTURE = 0xB4,
    /* 4.9 手指按压检测 - 0xB5*/
    FP_CMD0_FINGER_DETECT = 0xB5,
    /* 4.10 休眠模式 - 0xB6*/
    FP_CMD0_DO_IDLE = 0xB6,
    /* 4.11 查询模组UID - 0xC0*/
    FP_CMD0_MODULE_UID = 0xC0,
    /* 4.12 查询指纹sensor信息 - 0xC1*/
    FP_CMD0_SENSOR_INFO = 0xC1,
    /* 4.13 JTAG 控制 - 0xC2*/
    FP_CMD0_JTAG_CNTL = 0xC2,
    /* 4.14 恢复出厂设置 -0xC3 */
    FP_CMD0_RECOVERY_FACTORY = 0xC3,
    /* 4.15 固件升级 - 0xD0 */
    FP_CMD0_IAP_UPDATE = 0xD0,
    /* 4.16 运行模式切换 - 0xD1*/
    FP_CMD0_RUNNING_MODE = 0xD1,
    /* 控制输出IO电平 - 0xF0 */
    FP_CMD0_CTRL_OUTPUT_IO = 0xF0,
    /* 查询输入电平 - 0xF1 */
    FP_CMD0_QUERY_INPUT_IO = 0xF1,
} fingerprint_command0_t;

/* 通用正确回复码 */
#define FP_OK 0x00
/* 录入过程 */
#define FP_NOT_FINGER_DETECT  0x10 /* 无手指按下 */
#define FP_NOT_STABLE         0x11 /* 手指不稳定 */
#define FP_DUPLICATE          0x12 /* 手指已注册 */
#define FP_TEMPLATE_SAVE_FAIL 0x13 /* 模板保存失败 */
#define FP_OVERLAP            0x14 /* 重复面积 */
#define FP_NO_SPACE           0x15 /* 指纹已满 */
/* 识别过程 */
#define FP_TEMPLATE_NONE 0x20 /* 没有指纹录入 */
#define FP_NOT_MATCH     0x21 /* 比对失败 */
/* 录入/识别过程 */
#define FP_FINGER_UP    0x30 /* 手指离开 */
#define FP_ALGO_ERROR   0x31 /* 算法错误 */
#define FP_SPOOF_DETECT 0x32 /* 非活体 */
#define FP_TOO_WET      0x33 /* 指纹太湿 */
#define FP_TOO_DRY      0x34 /* 指纹太干 */
#define FP_PARTIAL      0x35 /* 指纹有效面积太小 */
#define FP_BAD_QUALITY  0x36 /* 指纹质量差 */
/* 删除过程 */
#define FP_NOT_EXIST 0x40 /* 指纹不存在 */
/* Flash操作错误 */
#define FP_FLASH_FATAL 0x41 /* FLASH 读写异常*/
/* 固件操作错误 */
#define FP_CRC_ERROR     0x50 /* 固件检验失败 */
#define FP_FW_TOO_BIG    0x51 /* 固件太大 */
#define FP_FW_TOO_SHORT  0x52 /* 固件接收长度太短 */
#define FP_GENERAL_ERROR 0x80 /* 通用错误码 */
/* Add other vendor error code */

#endif /* __BTL_PROTOCOL_PACKAGE_H__ */
